﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Forest.Cat.Domain.Entities.Resumes;
using Forest.Core;
using Forest.Core.Data;
using Forest.Core.Caching;
using Forest.Core.Events;
using Forest.Cat.Domain.Shared;

namespace Forest.Cat.Domain.Services.Resumes
{
    public class WorkExperienceService : IWorkExperienceService
    {
        #region Constants
        private const string WorkExperience_BY_ID_KEY = "workexperience.id-{0}";
        private const string WorkExperience_PATTERN_KEY = "workexperience.";
        #endregion

        #region Fields
        private readonly IRepository<WorkExperience> _workExperienceRepository;
        private readonly ICacheManager _cacheManager;
        private readonly IEventPublisher _eventPublisher;
        private readonly IGenerateNumberService _generateNumberService;
        #endregion

        #region Ctor
        public WorkExperienceService(IRepository<WorkExperience> workExperienceRepository,
            ICacheManager cacheManager, IEventPublisher eventPublisher, IGenerateNumberService generateNumberService)
        {
            _workExperienceRepository = workExperienceRepository;
            _cacheManager = cacheManager;
            _eventPublisher = eventPublisher;
            _generateNumberService = generateNumberService;
        }
        #endregion

        #region Base Methods
        public virtual void DeleteWorkExperience(WorkExperience workexperience)
        {
            if (workexperience == null)
                throw new ArgumentNullException("WorkExperience");

            _workExperienceRepository.Delete(workexperience);

            _cacheManager.RemoveByPattern(WorkExperience_PATTERN_KEY);
            //event notification
            _eventPublisher.EntityDeleted(workexperience);

        }

        public WorkExperience GetWorkExperienceById(Guid workexperienceId)
        {
            if (workexperienceId == Guid.Empty)
                return null;

            string key = string.Format(WorkExperience_BY_ID_KEY, workexperienceId);

            return _cacheManager.Get(key, () =>
            {
                var cl = _workExperienceRepository.GetById(workexperienceId);
                return cl;
            });
        }

        public virtual IPagedList<WorkExperience> GetAllWorkExperiences(int pageIndex, int pageSize)
        {
            var query = _workExperienceRepository.Table;
            query = query.OrderBy(w => w.Id);
            var items = new PagedList<WorkExperience>(query, pageIndex, pageSize);
            return items;
        }

        public virtual IList<WorkExperience> GetWorkExperiences(Guid resumeId)
        {
            var query = _workExperienceRepository.Table;
            query = query.Where(c => c.ResumeId == resumeId).OrderByDescending(c => c.LastUpdated);

            return query.ToList();
        }

        public virtual void InsertWorkExperience(WorkExperience workexperience)
        {
            if (workexperience == null)
                throw new ArgumentNullException("WorkExperience");

            _workExperienceRepository.Insert(workexperience);

            _cacheManager.RemoveByPattern(WorkExperience_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityInserted(workexperience);
        }

        public virtual void UpdateWorkExperience(WorkExperience workexperience)
        {
            if (workexperience == null)
                throw new ArgumentNullException("WorkExperience");
            _workExperienceRepository.Update(workexperience);

            _cacheManager.RemoveByPattern(WorkExperience_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityUpdated(workexperience);
        }
        #endregion

        public Guid CreateId
        {
            get
            {
                return _generateNumberService.GenerateId<WorkExperience>(_workExperienceRepository, GenerateType.Work);
            }
        }

        public bool HasWorkExperiences(Guid resumeId)
        {
            return _workExperienceRepository.Table.Any(w => w.ResumeId == resumeId);
        }
    }
}
